package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.*;
import com.tanhua.model.domain.*;
import com.tanhua.model.vo.*;
import com.tanhua.server.interceptor.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

@Service
@Slf4j
public class TestSoulService {

    @DubboReference
    private QuestionnaireApi questionnaireApi;

    @DubboReference
    private QuestionnaireLevelApi questionnaireLevelApi;

    @DubboReference
    private SoulQuestionApi soulQuestionApi;

    @DubboReference
    private SoulQuestionOptionApi soulQuestionOptionApi;

    @DubboReference
    private DimensionApi dimensionApi;

    @DubboReference
    private QuestionnaireReportApi questionnaireReportApi;

    @DubboReference
    private PersonalityTypeApi personalityTypeApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 问卷列表
     * @return
     */
    public List<QuestionnaireVo> questionnaireList() {
        List<QuestionnaireVo> returnList = new ArrayList<>();
        String report1 = null;
        String report2 = null;
        //获取所有问卷表
        List<Questionnaire> questionnaireList = questionnaireApi.findAll();
        for (Questionnaire questionnaire : questionnaireList) {
            //vo对象
            QuestionnaireVo questionnaireVo = new QuestionnaireVo();
            //问卷id
            Integer questionnaireId = questionnaire.getId();
            questionnaireVo.setId(questionnaireId.toString());
            questionnaireVo.setName(questionnaire.getName());
            questionnaireVo.setCover(questionnaire.getCover());
            questionnaireVo.setStar(questionnaire.getStar());
            //问卷等级id
            Integer levelId = questionnaire.getLevel();
            QuestionnaireLevel questionnaireLevel = questionnaireLevelApi.findById(levelId);

            questionnaireVo.setLevel(questionnaireLevel.getName());

            //问题vo
            List<SoulQuestionVo> questionVos = new ArrayList<>();
            //题目集合
            List<SoulQuestion> questionList = soulQuestionApi.findByQuestionnaireId(questionnaireId);
            for (SoulQuestion question : questionList) {
                SoulQuestionVo questionVo = new SoulQuestionVo();
                Integer questionId = question.getId();
                questionVo.setId(questionId.toString());
                questionVo.setQuestion(question.getStem());
                //选项vo
                List<SoulQuestionOptionVo> optionVos = new ArrayList<>();
                List<SoulQuestionOption> optionList = soulQuestionOptionApi.findByQuestionId(questionId);
                for (SoulQuestionOption option : optionList) {
                    SoulQuestionOptionVo optionVo = new SoulQuestionOptionVo();
                    optionVo.setId(option.getId().toString());
                    optionVo.setOption(option.getContent());
                    optionVos.add(optionVo);
                }
                questionVo.setOptions(optionVos);
                questionVos.add(questionVo);
            }
            questionnaireVo.setQuestions(questionVos);

            //从redis里查用户对这份问卷是否回答过
            String key = Constants.USER_QUESTIONNAIRE + UserHolder.getUserId();
            String hashKey = Constants.QUESTIONNAIRE_ID + questionnaireId;
            String reportId = (String) redisTemplate.opsForHash().get(key, hashKey);

            //回答过就把相应的信息设置到vo里面
            if (questionnaireId == 1) {
                //如果是第一份问卷，则不上锁
                questionnaireVo.setIsLock(0);
                if (reportId != null) {
                    //设置报告id
                    questionnaireVo.setReportId(reportId);
                    report1 = reportId;
                }
            }
            //如果第一份试卷报告不为空，那么给第二份试卷解锁
            if (report1 != null) {
                if (questionnaireId == 2) {
                    questionnaireVo.setIsLock(0);
                    questionnaireVo.setReportId(reportId);
                    report2 = reportId;
                }
            }
            if (report2 != null) {
                if (questionnaireId == 3) {
                    questionnaireVo.setIsLock(0);
                    questionnaireVo.setReportId(reportId);
                }
            }
            returnList.add(questionnaireVo);
        }
        return returnList;
    }

    /**
     * 提交问卷
     * @param answers
     * @return
     */
    public String commitQuestionnaire(Map<String, List<AnswersVo>> answers) {
        Long userId = UserHolder.getUserId();
        List<Long> waixiang = new ArrayList<>();//外向纬度值
        List<Long> panduan = new ArrayList<>();//判断纬度值
        List<Long> chouxiang = new ArrayList<>();//抽象纬度值
        List<Long> lixing = new ArrayList<>();//理性
        QuestionnaireReport report = new QuestionnaireReport();
        //问卷id
        Long questionnaireId = null;
        Collection<List<AnswersVo>> values = answers.values();
        for (List<AnswersVo> answersVos : values) {

            for (AnswersVo answersVo : answersVos) {
                Integer questionId = Integer.parseInt(answersVo.getQuestionId());
                Integer optionId = Integer.parseInt(answersVo.getOptionId());
                SoulQuestion question = soulQuestionApi.findById(questionId);

                if (question != null) {
                    questionnaireId = (long) question.getQuestionnaireId();

                    //根据question获取维度id
                    Integer dimensionId = question.getDimensionId();
                    //根据维度id查询对应的维度名称
                    String dimensionName = dimensionApi.findById(dimensionId);
                    if (dimensionName != null) {
                        if (dimensionName.equals(Constants.QUESTION_TYPE_WAIXIANG)) {
                            waixiang.add(optionId.longValue());
                        }
                        if (dimensionName.equals(Constants.QUESTION_TYPE_CHOUXIANG)) {
                            chouxiang.add(optionId.longValue());
                        }
                        if (dimensionName.equals(Constants.QUESTION_TYPE_LIXING)) {
                            lixing.add(optionId.longValue());
                        }
                        if (dimensionName.equals(Constants.QUESTION_TYPE_PANDUAN)) {
                            panduan.add(optionId.longValue());
                        }
                    }
                }
            }
        }

        //查询各维度分数
        Integer waiXiangSum = soulQuestionOptionApi.findByIds(waixiang);
        Integer chouXiangSum = soulQuestionOptionApi.findByIds(chouxiang);
        Integer liXingSum = soulQuestionOptionApi.findByIds(lixing);
        Integer panDuanSum = soulQuestionOptionApi.findByIds(panduan);
        //为report设置各参数
        report.setWaixiang(getPercentage(waiXiangSum, waixiang.size()));
        report.setChouxiang(getPercentage(chouXiangSum, chouxiang.size()));
        report.setPanduan(getPercentage(panDuanSum, panduan.size()));
        report.setLixing(getPercentage(liXingSum, lixing.size()));
        //设置最大维度
        report.setMaxValue(maxScore(waiXiangSum, panDuanSum, liXingSum, chouXiangSum));
        report.setQuestionnaireId(questionnaireId);
        report.setCreated(new Date());
        report.setUserId(userId);
        //报告id
        String reportId = questionnaireReportApi.insertOrUpdate(report).toString();

        String key = Constants.USER_QUESTIONNAIRE + userId;
        String hashKey = Constants.QUESTIONNAIRE_ID + questionnaireId;
        redisTemplate.opsForHash().put(key, hashKey, reportId);
        //返回reportId
        return reportId;
    }

    /**
     * 判断类型
     * @param waiXiangSum
     * @param panDuanSum
     * @param liXingSum
     * @param chouXiangSum
     * @return
     */
    private String maxScore(Integer waiXiangSum, Integer panDuanSum, Integer liXingSum, Integer chouXiangSum) {
        int sum = waiXiangSum + panDuanSum + liXingSum + chouXiangSum;
        //1.小于20.猫头鹰
        if (sum <= 20) {
            return Constants.QUESTION_TYPE_WAIXIANG;
            //2.21分-40分:白兔型
        } else if (sum >= 21 && sum <= 40) {
            return Constants.QUESTION_TYPE_PANDUAN;
            //41分-60分:狐狸型
        } else if (sum >= 41 && sum <= 60) {
            return Constants.QUESTION_TYPE_CHOUXIANG;
            //60以上：狮子型
        } else {
            return Constants.QUESTION_TYPE_LIXING;
        }
    }

    /**
     * 获取占比
     * @param total
     * @param listSize
     * @return
     */
    private String getPercentage(Integer total, int listSize) {
        BigDecimal bigDecimal = new BigDecimal(total / listSize);
        //四舍五入保留两位小数
        double value = bigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        if (value <= 1.5) {
            return "60%";
        } else if (value > 1.5 && value <= 2) {
            return "70%";
        } else if (value > 2 && value <= 4) {
            return "80%";
        } else {
            return "90%";
        }
    }

    /**
     * 查看报告
     * @param reportId
     * @return
     */
    public QuestionnaireReportVo getReport(Long reportId) {
        //返回的vo
        QuestionnaireReportVo reportVo = new QuestionnaireReportVo();
        //用户报告
        QuestionnaireReport report = questionnaireReportApi.findReport(reportId);
        if (report == null) {
            return reportVo;
        }
        String maxValue = report.getMaxValue();
        //维度
        Dimension dimension = dimensionApi.findTypeByName(maxValue);
        //维度对应的性格
        PersonalityType personalityType = personalityTypeApi.findById(dimension.getId());
        //各维度集合list
        List<Map<String, String>> list = new ArrayList<>();

        Map<String, String> waixiang = new HashMap<>();
        waixiang.put("key", "外向");
        waixiang.put("value", report.getWaixiang());

        Map<String, String> panduan = new HashMap<>();
        panduan.put("key", "判断");
        panduan.put("value", report.getPanduan());

        Map<String, String> chouxiang = new HashMap<>();
        chouxiang.put("key", "抽象");
        chouxiang.put("value", report.getChouxiang());

        Map<String, String> lixing = new HashMap<>();
        lixing.put("key", "理性");
        lixing.put("value", report.getLixing());

        //添加到维度集合
        list.add(waixiang);
        list.add(panduan);
        list.add(chouxiang);
        list.add(lixing);

        BeanUtils.copyProperties(personalityType, reportVo);
        reportVo.setDimensions(list);
        //和我相似的用户id集合
        List<Long> userIds = questionnaireReportApi.findSimilarUser(maxValue, report.getQuestionnaireId());

        //移除自己
        if (userIds.contains(UserHolder.getUserId())) {
            userIds.remove(UserHolder.getUserId());
        }

        //相似用户信息
        List<UserInfo> userInfoList = null;
        if (!CollUtil.isEmpty(userIds)) {
            userInfoList = userInfoApi.findByBatchIds(userIds);
        }
        reportVo.setSimilarYou(userInfoList);
        return reportVo;
    }
}
